package com.jse.json;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.jse.Fs;
import com.jse.Http;
import com.jse.Lang;

public class Json {

	public static Object parse(String s) {
		if(s==null)return null;
		s=s.trim();
		if(s.charAt(0)=='{')return new JsonObject(s);
		else if(s.charAt(0)=='[')return new JsonArray(s);
		else if(s.charAt(0)=='<')return XML.toJSONObject(s);
		else if(s.charAt(0)=='/')return parse(Fs.readString(s));
		else if(s.startsWith("http://")||s.startsWith("https://"))return parse(Http.get(s));
		else if(Fs.exists(s))return parse(Fs.readString(s));
		return s;
	}
	
	public static <T>T json(Object o) {//转化为jsonobject或jsonarray
		if(o instanceof JsonObject||o instanceof JsonArray)return (T)o;
		if(o instanceof Collection c)return (T)jsonArray(c);
		if(o instanceof Map c) {
			if(c.getClass().getName().endsWith(".ScriptObjectMirror")) {
    			if(c.toString().equals("[object Array]"))return (T)new JsonArray(c.values());
    		}
			return (T)jsonObject(c);
		}
		if(o instanceof String s)return (T)parse(s);
		return null;
	}

	public static JsonObject jsonObject(Object m) {
		if(m==null)return null;
		if(m instanceof JsonObject j)return j;
		if(m instanceof Map j)return new JsonObject(j);
		if(m instanceof Collection c) {
			JsonObject jo=new JsonObject(c.size());
			int i=0;for(var o:c)jo.put(""+i++,o);
			return jo;
		}
		if(m instanceof String s)return parse(s,JsonObject.class);
		return new JsonObject(m);
	}
	public static JsonArray jsonArray(Object m) {
		if(m instanceof JsonArray j)return j;
		if(m instanceof Collection c)return new JsonArray(c);
		if(m instanceof Map j)return new JsonArray(j);
		if(m instanceof String s)return parse(s,JsonArray.class);
		return new JsonArray(m);
	}

	public static String toJson(Object obj) {
		if(obj==null) {
    		return null;
    	}else if(obj instanceof JsonArray j) {
    		return j.toString();
    	}else if(obj instanceof JsonObject j) {
    		return j.toString();
    	}else if(obj instanceof String s) {
    		return s;
    	}else if(obj.getClass().isArray()) {
    		return new JsonArray(obj).toString();
    	}else if(obj instanceof Collection<?> c) {
    		return new JsonArray((Collection<?>)c).toString();
    	}else if(obj instanceof Map<?,?> j) {
    		if(j.getClass().getName().endsWith(".ScriptObjectMirror")) {
    			if(j.toString().equals("[object Array]"))return new JsonArray(j.values()).toString();
    		}
    		return new JsonObject((Map<?,?>)j).toString();
    	}else if(obj.getClass().getName().startsWith("java.")) {
    		return obj.toString();
    	}else {
    		return new JsonObject(obj).toString();
    	}
	}

	public static <T> T parse(String json,Class<T> c) {
		var o=parse(json);
		if(c.isInstance(o))return (T)o;
		if(o instanceof JsonObject j)return j.toBean(c);
		throw new RuntimeException("not cast class:"+c);
	}
	public static <T> T fromJson(Class<T> t, String s) {return parse(s,t);}
	public static <T> T fromJson(String s,Class<T> c) {return parse(s,c);}
	public static <T> T readJson(String p, Class<T> c){return parse(Fs.readString(p),c);}
	public static JsonObject prop(String path) {
		JsonObject jo=new JsonObject();
		Lang.properties(path).forEach((k,v)->{jo.put(k.toString(),v);});
		return jo;
	}
	
	/**
	 * 增强版path方法，支持更复杂的路径表达式
	 * @param o 要访问的对象
	 * @param path 路径表达式，支持以下格式：
	 *             - 简单属性访问: user.name
	 *             - 数组索引访问: users[0]
	 *             - 嵌套数组访问: matrix[0][1]
	 *             - 混合访问: users[0].address.city
	 *             - 多维数组: data[0][1][2]
	 * @return 找到的值，如果路径无效则返回null
	 */
	public static Object path(Object o, String path) {
		if(o == null || path == null || path.isEmpty()) {
			return null;
		}
		Object current = o;
		StringBuilder key = new StringBuilder();
		boolean inBracket = false;
		for(int i = 0; i < path.length(); i++) {
			char c = path.charAt(i);
			switch(c) {
				case '[':// 处理前面累积的key
					if(key.length() > 0) {
						current = jsonObject(current).get(key.toString());
						key.setLength(0);
					}
					inBracket = true;
					break;
				case ']':
					if(inBracket && key.length() > 0) {
						current = jsonArray(current).get(Integer.parseInt(key.toString()));
						key.setLength(0);
					}
					inBracket = false;
					break;
				case '.':
					if(!inBracket && key.length() > 0) {
						current = jsonObject(current).get( key.toString());
						key.setLength(0);
					}
					break;
				default:
					key.append(c);
			}
		}
		// 处理最后一个key
		if(key.length() > 0) {
			current = jsonObject(current).get(key.toString());
		}
		return current;
	}

	public static void main(String[] args) {
		var o=jsonObject(List.of(1,2,3));
		System.out.println(path(o,"[1]"));
	}

	

	
}
